﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace JeanFish.Common
{
    /// <summary>
    /// 反射辅助类。
    /// </summary>
    public static class ReflectionHelper
    {
        /// <summary>
        /// 根据成员获取对象的属性值。
        /// </summary>
        /// <typeparam name="TObj">对象类型</typeparam>
        /// <typeparam name="T">属性类型</typeparam>
        /// <param name="obj">对象</param>
        /// <param name="selector">成员表达式</param>
        /// <returns>属性值</returns>
        public static T SelectProperty<TObj, T>(this TObj obj, Expression<Func<TObj, T>> selector)
        {
            if (!(selector.Body is MemberExpression)) throw new ArgumentException();
            Type type = selector.Body.Type;
            if (type != typeof(T)) throw new NotSupportedException();
            MemberExpression memberExp = selector.Body as MemberExpression;
            string propertyName = memberExp.Member.Name;
            return (T)(typeof(TObj).GetProperty(propertyName).GetValue(obj));
        }

        public static T GetTypeAttribute<T>(this object obj, T defaultAttr = null)
            where T : Attribute
        {
            T attribute = obj.GetType().GetCustomAttribute<T>();
            if (attribute == null)
                attribute = defaultAttr;
            return attribute;
        }
        public static T GetFieldAttribute<T>(this object obj, string fieldName, T defaultAttr = null)
            where T : Attribute
        {
            FieldInfo field = obj.GetType().GetField(fieldName);
            T attribute = field.GetCustomAttribute<T>();
            if (attribute == null)
                attribute = defaultAttr;
            return attribute;
        }
        public static T GetPropertyAttribute<T>(this object obj, string propertyName, T defaultAttr = null)
            where T : Attribute
        {
            PropertyInfo property = obj.GetType().GetProperty(propertyName);
            T attribute = property.GetCustomAttribute<T>();
            if (attribute == null)
                attribute = defaultAttr;
            return attribute;
        }
    }
}
